package com.easyjava.vuebuilder;

import com.easyjava.bean.FieldInfo;
import com.easyjava.bean.TableInfo;
import com.easyjava.utils.MyStringUtils;
import com.easyjava.vuebean.ConstantsVue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: 小闹心
 * @Description: 生成接口api js
 * @DateTime: 2024/11/21 10:57
 **/
public class BuilderVueApis {
    public static final Logger logger = LoggerFactory.getLogger(BuilderVueApis.class);
    public static void execute(TableInfo tableInfo){
        File folder = new File(ConstantsVue.PATH_VUE_APIS);
        if(!folder.exists()){
            folder.mkdirs();
        }
        String fileName = MyStringUtils.lowerCaseFirstLetter(tableInfo.getBeanName() + "API");
        File javaFile = new File(folder,fileName + ".js");
        OutputStream out = null;
        OutputStreamWriter outWriter = null;
        BufferedWriter bw = null;
        try{
            out = new FileOutputStream(javaFile);
            outWriter = new OutputStreamWriter(out, StandardCharsets.UTF_8);
            bw = new BufferedWriter(outWriter);
            bw.write("import httpInstance from \"@" + ConstantsVue.PACKAGE_VUE_UTILS + "/httpUtils\";");
            bw.newLine();
            bw.write("import { toRefs } from \"vue\";");
            bw.newLine();
            bw.newLine();
            bw.write("// 分页查询");
            bw.newLine();
            bw.write("export function get" + tableInfo.getBeanName() + "ByPage(pageItem){");
            bw.newLine();
            bw.write("\tconst pageData = toRefs(pageItem);");
            bw.newLine();
            bw.write("\treturn httpInstance({");
            bw.newLine();
            bw.write("\t\tmethod: 'GET',");
            bw.newLine();
            String beanName = MyStringUtils.lowerCaseFirstLetter(tableInfo.getBeanName());
            bw.write("\t\turl: '/" + beanName + "/list',");
            bw.newLine();
            bw.write("\t\tparams: {");
            bw.newLine();
            bw.write("\t\t\t'pageNo': pageData.page.value,");
            bw.newLine();
            bw.write("\t\t\t'pageSize': pageData.size.value,");
            bw.newLine();
            String beanParamName = MyStringUtils.lowerCaseFirstLetter(tableInfo.getBeanParamName());
            for(FieldInfo fieldInfo : tableInfo.getFieldList()){
                bw.write("\t\t\t'" + MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()) + "': pageData." +
                        MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()) + ".value,");
                bw.newLine();
            }
            for(int i = 0; i < tableInfo.getFieldExtendList().size(); i++){
                FieldInfo fieldInfo = tableInfo.getFieldExtendList().get(i);
                bw.write("\t\t\t'" + MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()) + "': pageData." +
                        MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()) + ".value");
                if(i < tableInfo.getFieldExtendList().size() - 1){
                    bw.write(",");
                }
                bw.newLine();
            }
            bw.write("\t\t}");
            bw.newLine();
            bw.write("\t})");
            bw.newLine();
            bw.write("}");
            bw.newLine();
            bw.newLine();

            bw.write("// 添加数据");
            bw.newLine();
            bw.write("export function add" + tableInfo.getBeanName() + "(" + beanName +"Form){");
            bw.newLine();
            bw.write("\tconst " + beanName + " = toRefs("+ beanName + "Form)");
            bw.newLine();
            bw.write("\treturn httpInstance({");
            bw.newLine();
            bw.write("\t\tmethod: 'POST',");
            bw.newLine();
            bw.write("\t\turl: '/" + beanName + "/insert',");
            bw.newLine();
            bw.write("\t\tparams: {");
            bw.newLine();
            for(FieldInfo fieldInfo : tableInfo.getFieldList()){
                bw.write("\t\t\t'" + MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()) + "': " + beanName +"." + MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()) + ".value,");
                bw.newLine();
            }
            bw.write("\t\t}");
            bw.newLine();
            bw.write("\t})");
            bw.newLine();
            bw.write("}");
            bw.newLine();
            bw.newLine();

            // 生成唯一索引方法
            Map<String, List<FieldInfo>> keyIndexMap = tableInfo.getKeyIndexMap();
            for(Map.Entry<String, List<FieldInfo>> entry : keyIndexMap.entrySet()){
                List<FieldInfo> keyFields = entry.getValue();
                Integer index = 0;
                // getBy xxx方法
                StringBuilder methodName = new StringBuilder();
                // 方法参数 不带类型
                StringBuilder execParam = new StringBuilder();
                List<String> keyFieldsName = new ArrayList<>();
                for(FieldInfo fieldInfo : keyFields){
                    index++;
                    keyFieldsName.add(MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()));
                    methodName.append(MyStringUtils.upperCaseFirstLetter(MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName())));
                    execParam.append(MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()));
                    if(index < keyFields.size()){
                        methodName.append("And");
                        execParam.append(", ");
                    }
                }

                // 查询数据
                bw.write("// 根据" + methodName + "查询数据");
                bw.newLine();
                bw.write("export function get" + tableInfo.getBeanName() + "By" + methodName + "(" + execParam + ") {");
                bw.newLine();
                bw.write("\treturn httpInstance({");
                bw.newLine();
                bw.write("\t\tmethod: 'GET',");
                bw.newLine();
                bw.write("\t\turl:'/" + beanName + "/getBy" + methodName + "',");
                bw.newLine();
                bw.write("\t\tparams: {");
                bw.newLine();
                bw.write("\t\t\t" + execParam);
                bw.newLine();
                bw.write("\t\t}");
                bw.newLine();
                bw.write("\t})");
                bw.newLine();
                bw.write("}");
                bw.newLine();
                bw.newLine();
                // 修改数据
                bw.write("// 根据" + methodName + "修改数据");
                bw.newLine();
                bw.write("export function update" + tableInfo.getBeanName() + "By" + methodName + "(" + beanName + "Form, " + execParam + ") {");
                bw.newLine();
                bw.write("\tconst " + beanName + " = toRefs("+ beanName + "Form)");
                bw.newLine();
                bw.write("\treturn httpInstance({");
                bw.newLine();
                bw.write("\t\tmethod: 'POST',");
                bw.newLine();
                bw.write("\t\turl:'/" + beanName + "/updateBy" + methodName + "',");
                bw.newLine();
                bw.write("\t\tparams: {");
                bw.newLine();
                bw.write("\t\t\t" + execParam + ",");
                bw.newLine();
                for(FieldInfo fieldInfo : tableInfo.getFieldList()){
                    if(!keyFieldsName.contains(MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()))){
                        bw.write("\t\t\t'" + MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()) + "': " + beanName +"." + MyStringUtils.lowerCaseFirstLetter(fieldInfo.getPropertyName()) + ".value,");
                        bw.newLine();
                    }
                }
                bw.newLine();
                bw.write("\t\t}");
                bw.newLine();
                bw.write("\t})");
                bw.newLine();
                bw.write("}");
                bw.newLine();
                bw.newLine();

                // 删除数据
                bw.write("// 根据" + methodName + "删除数据");
                bw.newLine();
                bw.write("export function delete" + tableInfo.getBeanName() + "By" + methodName + "(" + execParam + ") {");
                bw.newLine();
                bw.write("\treturn httpInstance({");
                bw.newLine();
                bw.write("\t\tmethod: 'DELETE',");
                bw.newLine();
                bw.write("\t\turl:'/" + beanName + "/deleteBy" + methodName + "',");
                bw.newLine();
                bw.write("\t\tparams: {");
                bw.newLine();
                bw.write("\t\t\t" + execParam);
                bw.newLine();
                bw.write("\t\t}");
                bw.newLine();
                bw.write("\t})");
                bw.newLine();
                bw.write("}");
                bw.newLine();
                bw.newLine();

            }

            bw.flush();
        }catch (Exception e){
            logger.error("生成常量类: {} 失败" ,fileName);
        }finally {
            if(bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outWriter != null){
                try {
                    outWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
